﻿Imports MySql.Data.MySqlClient

''' <summary>
''' 技术备份设置界面
''' </summary>
''' <remarks></remarks>
Public Class frmSetting

    'Private Sub frmSetting_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
    '    Dim p As System.Drawing.Pen = New Drawing.Pen(Drawing.Color.Silver, 1)
    '    e.Graphics.DrawLine(p, 12, 91, 384, 91)
    '    e.Graphics.DrawLine(Drawing.Pens.SlateGray, 12, 90, 384, 90)

    '    e.Graphics.DrawLine(p, 12, 251, 384, 251)
    '    e.Graphics.DrawLine(Drawing.Pens.SlateGray, 12, 250, 384, 250)
    'End Sub

    Private Sub frmSetting_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        InitForm()
        InitData()
    End Sub

    ''' <summary>
    ''' 初始化数据
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub InitData()
        Dim sh As Schedule = Schedule.GetInstance
        ' 如果没有初始化过，则直接退出过程
        If (sh.Setting Is Nothing) Then
            Exit Sub
        End If

        With sh.Setting
            Me.chkEnable.Checked = .Enable
            numDay.Value = .Day
            Me.txtFolder.Text = .ToDirectory.Replace("/", "\")
            If (txtFolder.Text.Trim().Length > 0) Then
                ''=======================
                '' 存在备份路径，则进行检查
                CheckSpaces(txtFolder.Text)
            End If
            TimePicker.Value = New DateTime(Date.Now.Year, Date.Now.Month, Date.Now.Day, .StartTime.Hour, .StartTime.Minute, .StartTime.Second)

            If (Not .WeekDays Is Nothing) AndAlso .WeekDays.Length > 0 Then
                For Each itm As DayOfWeek In .WeekDays
                    SetCheckBox(itm)
                Next
            End If

            Me.ChangeGroup(.ExecuteCycle)
            Me.numBackFiles.Value = .BackupFilesCount
        End With

        DBSize = CheckDBSize()

    End Sub

    ''' <summary>
    '''  设置checkbox Checked属性
    ''' </summary>
    Private Sub SetCheckBox(ByVal wk As DayOfWeek)
        Select Case wk
            Case DayOfWeek.Sunday
                chk0.Checked = True
            Case DayOfWeek.Monday
                chk1.Checked = True
            Case DayOfWeek.Tuesday
                chk2.Checked = True
            Case DayOfWeek.Wednesday
                chk3.Checked = True
            Case DayOfWeek.Thursday
                chk4.Checked = True
            Case DayOfWeek.Friday
                chk5.Checked = True
            Case DayOfWeek.Saturday
                chk6.Checked = True
        End Select
    End Sub

    ''' <summary>
    ''' 改变groupbox及label的值
    ''' </summary>
    ''' <param name="etype">选择的类型</param>
    ''' <remarks>
    ''' 改变groupbox的现实和 label的值
    ''' </remarks>
    Private Sub ChangeGroup(ByVal etype As ExecutionCycles)
        Select Case etype
            Case ExecutionCycles.Days
                ' 隐藏全部gpbox
                Me.gpWeekly.Visible = False
                Me.gpMonthly.Visible = False
                Me.lblSchedule.Text = String.Format("从 {0} 起， 每天，{1}", DateTime.Now.ToShortDateString(), TimePicker.Value.TimeOfDay.ToString())

            Case ExecutionCycles.Weekly
                Me.gpMonthly.Visible = False
                Me.gpWeekly.Visible = True

                UpdateWeeklyLabel()

            Case ExecutionCycles.Monthly
                Me.gpWeekly.Visible = False
                Me.gpMonthly.Visible = True
                Me.lblSchedule.Text = String.Format("从 {0} 起， 在每月的第 {1} 天，{2}", DateTime.Now.ToShortDateString(), Me.numDay.Value, TimePicker.Value.TimeOfDay.ToString())
        End Select
    End Sub

    ''' <summary>
    ''' 初始化窗体控件
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub InitForm()

        Dim dt As DateTime
        dt = New DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 1, 0, 0)
        TimePicker.Value = dt
        Dim strs() As String = New String(2) {"每天", "每周", "每月"}
        cbType.Items.AddRange(strs)

        chk0.Checked = False
        chk1.Checked = False
        chk2.Checked = False
        chk3.Checked = False
        chk4.Checked = False
        chk5.Checked = False
        chk6.Checked = False

        Me.gpMonthly.Location = New System.Drawing.Point(12, 57)
        Me.gpWeekly.Location = New System.Drawing.Point(12, 57)
        Me.gpMonthly.Visible = False
        Me.gpWeekly.Visible = False

        chk0.Checked = True

        cbType.SelectedItem = "每天"
        Me.lblSchedule.Text = String.Format("从 {0} 起， 每天，{1}", DateTime.Now.ToShortDateString(), TimePicker.Value.TimeOfDay.ToString())
    End Sub

    ''' <summary>
    ''' 点击【应用】按钮时触发
    ''' </summary>  
    ''' <remarks>
    ''' 进行保存计划任务
    ''' </remarks>
    Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click

        '重置DialogResult
        Me.DialogResult = Windows.Forms.DialogResult.None

        If Windows.Forms.MessageBox.Show("确认要保存设置？", "系统提示", Windows.Forms.MessageBoxButtons.YesNo) = Windows.Forms.DialogResult.Yes Then
            ' 确认过需要保存
            Dim iCount As Integer = CInt(numBackFiles.Value)
            If (iCount * DBSize > TotalFreeSize) Then
                System.Windows.Forms.MessageBox.Show("备份需要的空间可能不足，请减少保留的备份文件数。", "系统提示", _
                        Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information)
                Return
            End If

            Dim sett As Setting = New Setting()
            sett.BackupFilesCount = iCount

            sett.StartTime = TimePicker.Value
            If txtFolder.Text <> "" Then
                sett.ToDirectory = txtFolder.Text
            Else
                sett.ToDirectory = Environment.CurrentDirectory.Replace("\", "/")
            End If
            sett.FromDBName = DBConfig.DatabaseName
            sett.Day = CInt(numDay.Value)

            If (cbType.SelectedItem = "每天") Then
                sett.ExecuteCycle = ExecutionCycles.Days

            ElseIf (cbType.SelectedItem = "每周") Then

                sett.ExecuteCycle = ExecutionCycles.Weekly

                Dim days As ArrayList = New ArrayList
                If (chk0.Checked) Then days.Add(DayOfWeek.Sunday)
                If (chk1.Checked) Then days.Add(DayOfWeek.Monday)
                If (chk2.Checked) Then days.Add(DayOfWeek.Tuesday)
                If (chk3.Checked) Then days.Add(DayOfWeek.Wednesday)
                If (chk4.Checked) Then days.Add(DayOfWeek.Thursday)
                If (chk5.Checked) Then days.Add(DayOfWeek.Friday)
                If (chk6.Checked) Then days.Add(DayOfWeek.Saturday)

                sett.WeekDays = days.ToArray(GetType(DayOfWeek))

            ElseIf (cbType.SelectedItem = "每月") Then
                sett.ExecuteCycle = ExecutionCycles.Monthly
            End If



            sett.Enable = chkEnable.Checked
            sett.IsIncrease = True

            Dim sh As Schedule = Schedule.GetInstance()
            sh.Stop()
            Dim cm As ConfigurationManager = New ConfigurationManager()
            cm.SaveSetting(sett)
            sh.Setting = sett
            System.Windows.Forms.MessageBox.Show("保存备份计划成功！", "系统提示", Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information)
            sh.Start()

            'Me.DialogResult = Windows.Forms.DialogResult.OK
        End If
    End Sub

    ''' <summary>
    ''' 点击【取消】按钮时触发
    ''' </summary>
    ''' <remarks>
    ''' 不保存计划任务，直接关闭窗体。
    ''' </remarks>
    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        Me.DialogResult = Windows.Forms.DialogResult.Cancel
    End Sub

    ''' <summary>
    ''' 当选择计划任务类型时触发
    ''' </summary>
    ''' <remarks>
    ''' 进行设置对应的界面
    ''' </remarks>
    Private Sub cbType_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cbType.SelectedIndexChanged
        If (cbType.SelectedItem = "每天") Then
            Me.ChangeGroup(ExecutionCycles.Days)
        ElseIf (cbType.SelectedItem = "每周") Then
            Me.ChangeGroup(ExecutionCycles.Weekly)
        ElseIf (cbType.SelectedItem = "每月") Then
            Me.ChangeGroup(ExecutionCycles.Monthly)
        End If
    End Sub

    ''' <summary>
    ''' 每月的第几天执行天数发生改变时触发
    ''' </summary>   
    ''' <remarks>
    ''' 更新label
    ''' </remarks>
    Private Sub numDay_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles numDay.ValueChanged
        Me.lblSchedule.Text = String.Format("从 {0} 起， 在每月的第 {1} 天，{2}", DateTime.Now.ToShortDateString(), numDay.Value.ToString, TimePicker.Value.TimeOfDay.ToString())
    End Sub

    ''' <summary>
    ''' checkbox check属性发送改变时触发
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub chk1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chk6.CheckedChanged, chk5.CheckedChanged, chk4.CheckedChanged, chk3.CheckedChanged, chk2.CheckedChanged, chk1.CheckedChanged, chk0.CheckedChanged
        UpdateWeeklyLabel()
    End Sub

    ''' <summary>
    ''' 更新Weekly 下Label
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub UpdateWeeklyLabel()
        Dim str As String = ""

        For Each item As Windows.Forms.Control In Me.gpWeekly.Controls
            If TypeOf item Is Windows.Forms.CheckBox Then
                If (CType(item, Windows.Forms.CheckBox).Checked) Then
                    str += item.Text + "，"
                End If
            End If
        Next
        If str <> "" Then str = str.Remove(str.Length - 1)
        Me.lblSchedule.Text = String.Format("从 {0} 起，每周的{1}，{2}", DateTime.Now.ToShortDateString(), str, TimePicker.Value.TimeOfDay.ToString())
    End Sub

    ''' <summary>
    ''' 时间发生改变时触发
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub TimePicker_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimePicker.ValueChanged
        If (cbType.SelectedItem = "每天") Then
            Me.lblSchedule.Text = String.Format("从 {0} 起， 每天，{1}", DateTime.Now.ToShortDateString(), TimePicker.Value.TimeOfDay.ToString())

        ElseIf (cbType.SelectedItem = "每周") Then
            UpdateWeeklyLabel()
        ElseIf (cbType.SelectedItem = "每月") Then
            Me.lblSchedule.Text = String.Format("从 {0} 起， 在每月的第 {1} 天，{2}", DateTime.Now.ToShortDateString(), Me.numDay.Value, TimePicker.Value.TimeOfDay.ToString())
        End If
    End Sub

    ''' <summary>
    ''' 选择备份文件保存的目录
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub btnSelectFolder_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSelectFolder.Click
        If (Me.FldBrowser.ShowDialog() = Windows.Forms.DialogResult.OK) Then
            If (CheckSpaces(FldBrowser.SelectedPath)) Then
                txtFolder.Text = FldBrowser.SelectedPath
            Else
                System.Windows.Forms.MessageBox.Show("你选择的备份文件路径所在的盘符空间太小，请重新选择。", "系统提示", _
                    Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Exclamation)
            End If
        End If
    End Sub

    Private Function CheckSpaces(ByVal path As String) As Boolean
        If DBSize = -1 Then
            DBSize = CheckDBSize()
        End If
        Dim ds() As System.IO.DriveInfo = System.IO.DriveInfo.GetDrives()
        Dim dir As System.IO.DriveInfo
        For i As Integer = 0 To ds.Length - 1
            If (ds(i).IsReady AndAlso ds(i).RootDirectory.Name = path.Substring(0, path.IndexOf("\", 0) + 1)) Then
                dir = ds(i)
                Exit For
            End If
        Next
        If (dir IsNot Nothing) Then
            TotalFreeSize = dir.TotalFreeSpace
        Else
            '  System.Windows.Forms.MessageBox.Show("你选择的备份文件路径不正确，请重新选择。", "系统提示", Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Exclamation)
            lblbkFiles.Text = String.Format("你选择的备份路径不正确，请从新选择")
            Return False
        End If
        Dim iG As Decimal = TotalFreeSize / 1024 / 1024 / 1024
        iG = Math.Round(iG, 2)
        ''=====================
        '' 数据库大小小于100M则按照100M计算
        If (DBSize < 104857600) Then
            DBSize = 104857600
        End If

        Dim ifen As Long = TotalFreeSize / DBSize

        If (ifen < 3) Then
            lblbkFiles.Text = String.Format("备份盘符的剩余空间为：{0} GB，系统至少保留3份备份文件。你选择的路径空间不足。", iG)
            Return False
        End If
        If ifen > 100 Then
            ifen = 100
        End If
        lblbkFiles.Text = String.Format("备份盘符的剩余空间为：{0} GB，建议保留{1}份备份文件,至少保留3份备份文件。", iG, ifen)
        Return True
    End Function

    Private TotalFreeSize As Long = 0L
    Private DBSize As Long = -1L

    ''' <summary>
    ''' 检查当前数据库的大小
    ''' </summary>
    ''' <returns></returns>
    Shared Function CheckDBSize() As Integer

        Dim strSql As String = String.Empty
        strSql = String.Format("SELECT SUM(DATA_LENGTH) + SUM(INDEX_LENGTH) AS DataLength FROM INFORMATION_SCHEMA.PARTITIONS " & _
                               "WHERE TABLE_SCHEMA='{0}'", Encryptor.Decrypt(DBConfig.DatabaseName))

        Dim conn As MySqlConnection
        Try
            conn = New MySqlConnection(ConfigurationManager.ConnectionString)
            Dim cmd As MySqlCommand = New MySqlCommand(strSql, conn)
            conn.Open()
            Dim iSize As ULong
            iSize = CLng(cmd.ExecuteScalar())
            Return iSize
        Catch ex As Exception
#If DEBUG Then
            System.Diagnostics.Debug.Print(ex.Message)
#End If
        Finally
            If (conn.State <> ConnectionState.Closed) Then
                conn.Close()
            End If
        End Try

        Return -1
    End Function

    Private Sub numBackFiles_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles numBackFiles.ValueChanged
        If (DBSize = -1) Then
            Return
        End If

        Dim ivalue As Integer = CInt(numBackFiles.Value)
        If (ivalue * DBSize > TotalFreeSize) Then
            System.Windows.Forms.MessageBox.Show("备份需要的空间可能不足，请减少保留的备份文件。", "系统提示", _
                    Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information)

        End If
    End Sub
End Class